package com.jrx.anytxn.transaction.service.impl;

import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanUtils;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.transaction.bean.*;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmAccountMainInfo;
import com.jrx.anytxn.transaction.entity.TlGlInterfaceInfo;
import com.jrx.anytxn.transaction.service.IGlInterfaceService;
import com.jrx.anytxn.transaction.service.ITransferTypeStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.Date;
import java.util.Optional;

/**
 * @program: anytxn-cf-transaction
 * @description: 交易账户转列策略
 * @author: xiaoyu.jing
 * @date: 2019-11-15 19:31
 **/
@Service
public class AcctTransferTypeStrategy implements ITransferTypeStrategy<AmAccountMainInfo> {
    private static final Logger logger = LoggerFactory.getLogger(AcctTransferTypeStrategy.class);


    @Autowired
    private IGlInterfaceService glInterfaceService;


    /**
     * 交易账户外转列处理 会计状态升级，转表外，五级分类升级
     *
     * @param transferBean
     * @return
     * @throws TxnException
     */
    @Override
    public TransferSaveBean transferOut(TransferBean<AmAccountMainInfo> transferBean) throws TxnException {
        AmAccountMainInfo acct = transferBean.getTransferObject();
        logger.info("交易账户外转列acct:{}", BeanUtils.toMap(acct));
        DelqParamBean delqParamBean = transferBean.getDelqParamBean();
        Date bussinessDate = transferBean.getBussinessDate();
        int accountingDays = transferBean.getAccountingDays();
        int nonAccrualDays = transferBean.getNonAccrualDays();
        int classifyDays = transferBean.getClassifyDays();
        TransferSaveBean transferSaveBean = new TransferSaveBean();
        AmAccountMainInfo updateAcct = new AmAccountMainInfo();
        updateAcct.setId(acct.getId());
        updateAcct.setCustomerId(acct.getCustomerId());
        updateAcct.setTenantId(acct.getTenantId());
        String tempAccountStatus = acct.getAccountingPhase();
        boolean isUpdate = false;

        //五级分类
        String classify = delqParamBean.getDelqClassifyBeanList().stream()
                .filter(bean -> classifyDays >= bean.getClassifyDays())
                .map(DelqClassifyBean::getClassifyType)
                .max(String::compareTo)
                .orElse("0");

        String classifyReversible = delqParamBean.getDelqClassifyBeanList().get(0).getClassifyReversible();
        String beforeStatus = acct.getLoanClassify();

        if(TransBizConstant.YES_FLAG.equals(classifyReversible)){
            //可逆
            //如果与原状态不同则修改
            if (!classify.equals(beforeStatus)) {
                isUpdate = true;
                updateAcct.setLoanClassify(classify);
                acct.setLoanClassify(classify);
            }
        }else{
            //不可逆 新分类 大于原分类 才修改
            if(Integer.parseInt(classify) > Integer.parseInt(beforeStatus)){
                isUpdate = true;
                updateAcct.setLoanClassify(classify);
                acct.setLoanClassify(classify);
            }
        }

        //应计/非应计，根据交易账户类型获取对应的参数
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(acct.getAccountType());
        logger.info("应计/非应计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqNonAccrualBean), acct.getNonAccrualsFlag());
        //延滞天数>=转列天数
        if (nonAccrualDays >= delqNonAccrualBean.getTransDays()) {
            //允许转列
            if (TransBizConstant.TRANSFER_FLAG_1.equals(delqNonAccrualBean.getNonAccrualFlag())
                    && TransBizConstant.NON_ACCRUALS_FLA_0.equals(acct.getNonAccrualsFlag())) {
                isUpdate = true;
                String txnCode = delqNonAccrualBean.getNonTxnCode();
                String taxTxnCode = delqNonAccrualBean.getNonTaxTxnCode();
                updateAcct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_1);
                //非应计转列   金额为不含税金额、税分开转
                TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(acct, acct.getCurrBalance().subtract(acct.getTaxAmt()), txnCode, tempAccountStatus, bussinessDate);
                TlGlInterfaceInfo taxGlInterfaceInfo = glInterfaceService.buildTaxTlGlInterfaceInfo(acct, acct.getCurrBalance(),acct.getTaxAmt(), taxTxnCode, tempAccountStatus, bussinessDate);
                logger.info("应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
                logger.info("税金应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(taxGlInterfaceInfo));
                Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
                Optional.ofNullable(taxGlInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
                acct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_1);
            }

            //整笔转逾期,此时处理为逾期天数不满足转逾期条件的账户
            if (TransBizConstant.TRANSFER_FLAG_2.equals(delqNonAccrualBean.getNonAccrualFlag())
                    && TransBizConstant.ACCOUNTING_PHASE_0.equals(acct.getAccountingPhase())) {
                isUpdate = true;
                DelqAccountBean delqAccountBean = delqParamBean.getDelqAccountBeanList().stream()
                        .filter(bean -> bean.getAccountType().contains(acct.getAccountType()))
                        .filter(bean -> TransBizConstant.ACCOUNTING_PHASE_1.equals(bean.getAccountingPhase()))
                        .findFirst()
                        .orElseThrow(() -> new TxnBizException(ErrorMsgConstant.SYSTEM_PARAMETER_EXISTS));
                String txnCode = delqAccountBean.getTxnCode();
                updateAcct.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_1);
                //会计状态转列   金额为含税金额
                TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(acct, acct.getCurrBalance(), txnCode, tempAccountStatus, bussinessDate);
                logger.info("整笔转逾期当期转逾期GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
                Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
                acct.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_1);
            }
        }

        //会计状态转列处理，获取转列天数小于延滞天数，取会计状态最大的那个
        DelqAccountBean delqAccountBean = delqParamBean.getDelqAccountBeanList().stream()
                .filter(bean -> bean.getAccountType().contains(acct.getAccountType()))
                .filter(bean -> accountingDays >= bean.getTransferDays())
                .filter(bean -> TransBizConstant.TRANSFER_FLAG_1.equals(bean.getTransferFlag()))
                .max(Comparator.comparing(DelqAccountBean::getAccountingPhase))
                .orElseThrow(() -> new TxnBizException(ErrorMsgConstant.SYSTEM_PARAMETER_EXISTS));

        String accountingPhase = delqAccountBean.getAccountingPhase();
        logger.info("会计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqAccountBean), accountingPhase);
        //如果允许转列
        if (delqAccountBean.getAccountingPhase().compareTo(tempAccountStatus) > 0
                && TransBizConstant.NON_ACCRUALS_FLA_0.equals(acct.getNonAccrualsFlag())) {
            isUpdate = true;
            String txnCode = delqAccountBean.getTxnCode();
            updateAcct.setAccountingPhase(accountingPhase);
            acct.setAccountingPhase(accountingPhase);
            //会计状态转列   金额为含税金额
            TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(acct, acct.getCurrBalance(), txnCode, tempAccountStatus, bussinessDate);
            logger.info("会计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
            Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
        }

        if (isUpdate) {
            transferSaveBean.setUpdateAcct(updateAcct);
            return transferSaveBean;
        }
        return null;
    }


    /**
     * 交易账户内转列出处理 会计状态降级，转应计，五级分类降级
     *
     * @param transferBean
     * @return
     * @throws TxnException
     */
    @Override
    public TransferSaveBean transferIn(TransferBean<AmAccountMainInfo> transferBean) throws TxnException {

        AmAccountMainInfo acct = transferBean.getTransferObject();
        logger.info("交易账户内转列acct:{}", BeanUtils.toMap(acct));
        DelqParamBean delqParamBean = transferBean.getDelqParamBean();
        Date bussinessDate = transferBean.getBussinessDate();
        int accountingDays = transferBean.getAccountingDays();
        int nonAccrualDays = transferBean.getNonAccrualDays();
        int classifyDays = transferBean.getClassifyDays();
        //五级账户是否可逆 0 否 1 是
        String classifyReversible = delqParamBean.getDelqClassifyBeanList().get(0).getClassifyReversible();
        TransferSaveBean transferSaveBean = new TransferSaveBean();
        AmAccountMainInfo updateAcct = new AmAccountMainInfo();
        updateAcct.setId(acct.getId());
        updateAcct.setCustomerId(acct.getCustomerId());
        updateAcct.setTenantId(acct.getTenantId());
        String tempAccountStatus = acct.getAccountingPhase();
        boolean isUpdate = false;

        //五级分类
        String classify = delqParamBean.getDelqClassifyBeanList().stream()
                .filter(bean -> classifyDays >= bean.getClassifyDays())
                .filter(bean -> bean.getClassifyType().compareTo(acct.getLoanClassify()) <= 0)
                .map(DelqClassifyBean::getClassifyType)
                .max(String::compareTo)
                .orElse("0");

        //五级账户 可逆才可以修改状态
        if(TransBizConstant.YES_FLAG.equals(classifyReversible)){
            if (!classify.equals(acct.getLoanClassify())) {
                isUpdate = true;
                updateAcct.setLoanClassify(classify);
                acct.setLoanClassify(classify);
            }
        }


        //应计/非应计，根据交易账户类型获取对应的参数
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(acct.getAccountType());
        logger.info("应计/非应计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqNonAccrualBean), acct.getNonAccrualsFlag());
        //延滞天数<转列天数
        if (nonAccrualDays < delqNonAccrualBean.getTransDays()) {
            //允许转列
            if (TransBizConstant.TRANSFER_FLAG_1.equals(delqNonAccrualBean.getNonAccrualFlag())
                    && TransBizConstant.NON_ACCRUALS_FLA_1.equals(acct.getNonAccrualsFlag())) {
                isUpdate = true;

                // 表外交易的转回表内 交易码转为T58XXX
                String txnCode = delqNonAccrualBean.getInNonTxnCode();
                String taxTxnCode = delqNonAccrualBean.getInNonTaxTxnCode();

                //表内交易的转表外后转回表内 交易码转为T56XXX 表内交易账户txnCode为5XXXX 表外交易账户txnCode为9XXXX
                if(!TransBizConstant.ACCOUNT_TYPE_06.equals(acct.getAccountType()) && "5".equals(acct.getTxnCode().substring(1,2))){
                    txnCode = txnCode.substring(0,1)+(Integer.parseInt(txnCode.substring(1))-2000);
                    taxTxnCode = taxTxnCode.substring(0,1)+(Integer.parseInt(taxTxnCode.substring(1))-2000);
                }
                updateAcct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
                //非应计转列   金额为不含税金额、税分开转
                TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(acct, acct.getCurrBalance().subtract(acct.getTaxAmt()), txnCode, tempAccountStatus, bussinessDate);
                TlGlInterfaceInfo taxGlInterfaceInfo = glInterfaceService.buildTaxTlGlInterfaceInfo(acct,acct.getCurrBalance(),acct.getTaxAmt(),taxTxnCode, tempAccountStatus, bussinessDate);
                logger.info("应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
                logger.info("税金应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(taxGlInterfaceInfo));
                Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
                Optional.ofNullable(taxGlInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
                acct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
            }
        }

        //会计状态转列处理，获取转列天数小于延滞天数并且允许转列的参数，取会计状态最大的那个
        DelqAccountBean delqAccountBean = delqParamBean.getDelqAccountBeanList().stream()
                .filter(bean -> bean.getAccountType().contains(acct.getAccountType()))
                .filter(bean -> accountingDays >= bean.getTransferDays())
                .filter(bean -> TransBizConstant.TRANSFER_FLAG_1.equals(bean.getTransferFlag()))
                .filter(bean -> bean.getAccountingPhase().compareTo(acct.getAccountingPhase()) <= 0)
                .max(Comparator.comparing(DelqAccountBean::getAccountingPhase))
                .orElseThrow(() -> new TxnBizException(ErrorMsgConstant.SYSTEM_PARAMETER_EXISTS));

        //判断会计状态是否不等，则更新会计状态，并且生成转列GL流水
        //本金应计/非应计方式如果为整笔转逾期。则转回时统一在会记转列处理
        String accountingPhase = delqAccountBean.getAccountingPhase();
        logger.info("会计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqAccountBean), tempAccountStatus);
        if (!tempAccountStatus.equals(accountingPhase) && TransBizConstant.NON_ACCRUALS_FLA_0.equals(acct.getNonAccrualsFlag())) {
            if(TransBizConstant.ACCOUNT_TYPE_06.equals(transferBean.getAccountType())
                    && transferBean.getMaxDelqDays() >= delqNonAccrualBean.getTransDays()
                    && TransBizConstant.TRANSFER_FLAG_2.equals(delqNonAccrualBean.getNonAccrualFlag())) {
                //主要用于排除逾期天数不满足转逾期，但是订单状态为非应计的交易账户回转
                logger.info("本金交易账户,如果转列方式为整笔转逾期，并且当前订单为非应计状态，则不进行会记状态转列");
            }else {
                isUpdate = true;
                String txnCode = delqAccountBean.getTxnCode();
                updateAcct.setAccountingPhase(accountingPhase);
                acct.setAccountingPhase(accountingPhase);
                //会计状态转列   金额为含税金额
                TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(acct, acct.getCurrBalance(), txnCode, tempAccountStatus, bussinessDate);
                logger.info("会计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
                Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
            }
        }

        if (isUpdate) {
            transferSaveBean.setUpdateAcct(updateAcct);
            return transferSaveBean;
        }
        return null;
    }

    public static void main(String args[]){
        String a="I58110";
        String b = a.substring(0,1)+(Integer.parseInt(a.substring(1))-2000);
        System.out.println(b);
    }
}
